import {Scope} from 'lib/scopeFactory';
import ApiFactory from 'lib/ApiFactory'
import moment from 'moment'
import _ from 'underscore'
import numeral from 'numeral'
import $ from 'jquery'
import React from 'react'

let defaultFetcher = ApiFactory({
  url: (params) => {
    return BlueWare.urlPrefix + '/app/' + params.appId + '/' + params.segment + '/' + params.action + '.json';
  },
  optionParams: ['appId','segment','action','dateType'],
  params: {
    appId: {
      defaultValue: BlueWare.appId
    },
    segment: {
      defaultValue: 'anr'
    },
    action: {
      defaultValue: 'anrdetail'
    },
    appVersionId:{
      defaultValue:BlueWare.appVersionId
    }
  }
});

let defaultPoster = ApiFactory({
  url: (params) => {
    return BlueWare.urlPrefix + '/app/' + params.appId + '/' + params.segment + '/' + params.action + '.json';
  },
  optionParams: ['appId','segment','action','dateType'],
  method: 'post',
  params: {
    appId: {
      defaultValue: BlueWare.appId
    },
    segment: {
      defaultValue: 'anr'
    },
    action: {
      defaultValue: 'markanrstatus'
    }
  }
});

export default class DetailScope extends Scope {

  constructor(props) {
    super(props);

    this.anrTypeId = props.routeParams.anrTypeId;
    this.endTime = props.routeParams.endTime === 'null' ? null : props.routeParams.endTime;

    this.closeOtherDateMenu = this.closeOtherDateMenu.bind(this);

    this.$state = {
      // anr detail
      model:{},

      anrRate: '--',
      anrCount: '--',
      anrUserCount: '--',

      // chartLine data source
      chartLine: {
        loading: true
      },

      // chartLine cache
      chartLineDataSource: {},
      chartLineDateCheckStatus: {
        'today': true,
        'yesterday': false
      },
      chartLineSettings: {
        xAxis: {
          max: moment().startOf('day').add(1, 'days').subtract(1, 'hours').valueOf(),
          min: moment().startOf('day').valueOf()
        },
        tooltip: {
          useHTML: true
        }
      },

      // chartLine date list
      chartLineDateListSelectedValue: null,
      chartLineDateListOpened: false,
      chartLineDateList: [
        {label: '清除选择', value: null},
        {label: '2 天前', value: 2},
        {label: '3 天前', value: 3},
        {label: '4 天前', value: 4},
        {label: '5 天前', value: 5},
        {label: '6 天前', value: 6},
        {label: '7 天前', value: 7},
        {label: '15 天前', value: 15},
        {label: '30 天前', value: 30}
      ],

      chartPie: {
        loading: true
      },

      chartPie2: {
        loading: true
      },

      chartSettings: {
        legend: {
          layout: 'vertical',
          align: 'right',
          verticalAlign: 'middle',
          x: -50,
          navigation: {
            animation: true
          }
        },
        plotOptions: {
          pie: {
            dataLabels: {
              enabled: false
            },
            showInLegend: true
          }
        }
      },

      contentOffset: 0,
      content: {}
    };

    this.detailApi = defaultFetcher({
      anrTypeId: this.anrTypeId,
      endTime: this.endTime,
      action: 'anrlisttable'
    });

    this.changeStatusCodeApi = defaultPoster({
      anrTypeId: this.anrTypeId,
      status:()=>this.$state.model.statusCode,
      csrf_token:()=> BlueWare['CSRFTOKEN']
    });

    this.chartLineApi = defaultFetcher({
      anrTypeId: this.anrTypeId,
      endTime: this.endTime,
      timeUnit: 'hourly',
      dateType: 'today',
      action: 'anrdata'
    });

    this.TopbarApi = defaultFetcher({
      anrTypeId: this.anrTypeId,
      endTime: this.endTime,
      timeUnit: 'daily',
      action: 'anrdata'
    });

    this.$state.chartLineformatter = function () {
      let begin = moment(this.x).format('HH:mm');
      let end = moment(this.x + moment.duration(1, 'hours').valueOf()).format('HH:mm');

      let template = '<span>从 ' + begin + ' 到 '+ end + ' 的一小时内</span><br/>';

      template += _.map(this.points, (item) => {
        return '<span style="color:' + item.series.color + '">' + item.series.name + '</span><span style="margin-right: 8px"></span> ANR 率 : ' + numeral(item.y).format('0[.]00%') + '<span style="margin-right: 8px"></span> 活跃用户数 : ' + item.point.customData.alive;
      }).join('<br />');

      return template;
    };

    this.$state.chartPieFormatter = function () {
      return '<span style="color:' + this.point.color + '">' + this.key + '：<b>' + numeral(this.y).format('0[.]00%') + '</b></span>';
    }

    this.chartPieApi = defaultFetcher({
      anrTypeId: this.anrTypeId,
      endTime: this.endTime,
      action: 'anrchart',
      classify: 'model',
      limit: 9
    });

    this.chartPie2Api = defaultFetcher({
      anrTypeId: this.anrTypeId,
      endTime: this.endTime,
      action: 'anrchart',
      classify: 'osversion',
      limit: 5
    });

    this.contentApi = defaultFetcher({
      anrTypeId: this.anrTypeId,
      endTime: this.endTime,
      action: 'anrdetail',
      offset: () => this.$state.contentOffset
    })
  }

  $toggle_date_other_display() {
    this.$state.chartLineDateListOpened = !this.$state.chartLineDateListOpened;
    this.emit();
  }

  $custom_date_check(payload) {

    let targetValue = payload.item.value;
    if (!this.checkDateStatus(targetValue)) {
      return;
    }

    this.$state.chartLineDateListSelectedValue = targetValue;
    this.$state.chartLineDateListOpened = !this.$state.chartLineDateListOpened;

    if (targetValue && !this.$state.chartLineDataSource[targetValue.toString()]) {
      this.fetch_chartLine_data(targetValue).done(() => {
        this.emit();
      });
    } else {
      this.refillChartLine();
      this.emit();
    }
  }

  $predefined_date_check(payload) {
    let checked = this.$state.chartLineDateCheckStatus[payload.dayUnit] = !this.$state.chartLineDateCheckStatus[payload.dayUnit];

    if(!this.checkDateStatus()) {
      this.$state.chartLineDateCheckStatus[payload.dayUnit] = !checked;
      return;
    }

    if (checked) {
      this.fetch_chartLine_data(payload.dayUnit).done(() => {
        this.emit();
      });
    } else {
      this.refillChartLine();
      this.emit();
    }
  }

  fetch_chartLine_data(dateName) {
    this.$state.chart = { loading: true };
    this.emit();

    let deferred = $.Deferred();
    if(!this.$state.chartLineDataSource[dateName]) {
      this.chartLineApi.fetch((options) => {
        switch (dateName) {
          case 'today':
            options.data.endTime = moment().valueOf();
            break;
          case 'yesterday':
            options.data.endTime = moment().subtract(1, 'days').endOf('day').valueOf();
            break;
          default:
            if (typeof dateName === 'number') {
              options.data.endTime = moment().subtract(dateName, 'days').endOf('day').valueOf();
            }
            break;
        }
        return options;
      }).done((json, params) => {

        this.$state.chartLineDataSource[dateName.toString()] = {json, dateName};

        this.refillChartLine();

        deferred.resolve();
      }).fail((err) => {
        this.$state.chartLineDateCheckStatus[dateName.toString()] = null;
        this.$state.chartLineDataSource[dateName.toString()] = null;

        this.emit();
        deferred.reject(err);
      });
    } else {
      this.refillChartLine();
      deferred.resolve();
    }

    return deferred.promise();
  }

  refillChartLine() {

    for (let item in this.$state.chartDataSource) {
      if (isNaN(parseInt(item)) && !this.$state.chartDataSource[item]) {
        this.$state.chartDateCheckStatus[item] = false;
      } else if (!this.$state.chartDataSource[item]) {
        this.$state.chartDateListSelectedValue = null;
      }
    }

    let dateNames = [];
    let status = this.$state.chartLineDateCheckStatus;
    for (let item in status) {
      if (status[item]) {
        dateNames.push(item);
      }
    }

    let series = [];
    let dataSource = this.$state.chartLineDataSource;
    for (let i = 0; i < dateNames.length; i++) {
      series.push(dataSource[dateNames[i]]);
    }

    let customStatus = this.$state.chartLineDateListSelectedValue;
    if (customStatus && dataSource[customStatus.toString()]) {
      series.push(dataSource[customStatus.toString()]);
    }

    //////////////////////////////////
    let list = series.map((item) => {
      let {dateName, json} = item;

      let spanTime = 0;
      switch (dateName) {
        case 'yesterday':
          spanTime = moment.duration(1, 'days').valueOf();
          break;
        default:
          if (typeof dateName === 'number') {
            spanTime = moment.duration(dateName, 'days').valueOf();
          }
          break;
      }

      let data = json.map((innerItem) => {
        return {
          x: innerItem.startTime + spanTime,
          y: innerItem.alive === 0 ? 0 : (innerItem.affected / innerItem.alive),
          customData: {
            alive: innerItem.alive
          }
        };
      });

      let result = {
        id: moment().valueOf(),
        data: data
      };

      switch (dateName) {
        case 'today':
          result.name = '今天';
          break;
        case 'yesterday':
          result.name = '昨天';
          break;
        default:
          result.name = dateName + ' 天前';
          break;
      }

      return result;
    });
    //////////////////////////////////////////////////////////

    this.$state.chartLine = {
      data: {
        yAxis: {
          offset: -5,
          labels: {
            formatter: function() {
              return numeral(this.value).format('0[.]00%');
            }
          }
        },
        series: list
      }
    };
  }

  checkDateStatus(value) {
    let state = _.some(this.$state.chartLineDateCheckStatus, (item) => item);
    if (!state) {
      value = undefined === value ? this.$state.chartLineDateListSelectedValue : value;
      state = value !== null;
    }
    return state;
  }

  $change_status_code(payload) {
    let originValue = this.$state.model.statusCode;
    this.$state.model.statusCode = payload.value;
    this.changeStatusCodeApi.post().done((json, params) => {
      if (!json.result) {
        console.log(json.reason);
      }
      this.emit();
    }).fail((err, params) => {
      this.$state.model.statusCode = originValue;
      this.emit();

      console.log(err);
    });
  }

  $offset_content(payload) {
    this.$state.contentOffset += payload.isAdd ? 1 : -1;

    this.load_content();
  }

  $change_content_offset(payload) {
    this.$state.contentOffset = payload.value;

    this.load_content();
  }

  load_content() {
    this.contentApi.fetch().done((json, params) => {
      this.$state.content = json;
      this.emit();
    }).fail((err, params) => {
      console.log(err);
    });
  }

  $load() {
    $('body').on('click', this.closeOtherDateMenu);

    this.detailApi.fetch().done((json, params) => {
      this.$state.model = json[0];
      this.emit();
    }).fail(() => {
      this.$state.model = {};
      this.emit();
    });

    this.fetch_chartLine_data('today').done(() => {
      this.emit();
    });

    this.TopbarApi.fetch().done((json) => {
      let item = json[0];

      _.extend(this.$state, {
        anrRate: item.alive === 0 ? '--' : numeral(item.affected / item.alive).format('0[.]00%'),
        anrCount: item.count,
        anrUserCount: item.affected
      });

      this.emit();
    }).fail(() => {
      _.extend(this.$state, {
        anrRate: 'error',
        anrCount: 'error',
        anrUserCount: 'error'
      });
      this.emit();
    });

    this.chartPieApi.fetch().done((json, params) => {

      let calculated = 0;

      this.$state.chartPie = {
        data: {
          series: json.result.map((item, index) => {
            let percent = item.combData.count / json.totalCount;
            calculated += percent;
            return {
              id: index + 1,
              name: item.key.name,
              data:[{y:percent}]
            };
          })
        }
      };

      let otherValue = 1-calculated;
      if (otherValue > 0) {
        this.$state.chartPie.data.series.push({
          id: 10,
          name: '其它',
          data:[{y:otherValue}]
        });
      }
      this.emit();
    }).fail((err, params) => {
      console.log(err);
    });

    this.chartPie2Api.fetch().done((json, params) => {

      let calculated = 0;

      this.$state.chartPie2 = {
        data: {
          series: json.result.map((item, index) => {
            let percent = item.combData.count / json.totalCount;
            calculated += percent;
            return {
              id: index + 1,
              name: item.key.name,
              data:[{y:percent}]
            };
          })
        }
      };

      let otherValue = 1-calculated;
      if (otherValue > 0) {
        this.$state.chartPie2.data.series.push({
          id: 6,
          name: '其它',
          data:[{y:otherValue}]
        });
      }

      this.emit();
    }).fail((err, params) => {
      console.log(err);
    });

    this.load_content();
  }

  $unload() {
    $('body').off('click', this.closeOtherDateMenu);
  }

  closeOtherDateMenu(e) {
    if (this.$state.chartLineDateListOpened) {
      let el = e.target
        , container = this.viewInstance.refs.dateOtherRoot;

      if (!$.contains(container,el)) {
        this.$state.chartLineDateListOpened = false;
        this.emit();
      }
    }
  }
}
